#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "light_sensor.h"

#include "MQTTClient.h" //mqtt三方库
#include "cJSON.h"      //cJson解析三方库



#include "wifi_connecter.h" // easy wifi (station模式)
#include "iot_watchdog.h" 




// 定义一个宏，用于标识SSID。请根据实际情况修改
#define PARAM_HOTSPOT_SSID "1"

// 定义一个宏，用于标识密码。请根据实际情况修改
#define PARAM_HOTSPOT_PSK "12345678"

// 定义一个宏，用于标识加密方式
#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK



// 定义一个宏，用于标识MQTT服务器IP地址。请根据实际情况修改
#define HOST_ADDR "9ba2353c03.iot-mqtts.cn-north-4.myhuaweicloud.com"


// 定义一个宏，用于标识MQTT服务器端口
#define HOST_PORT 1883

// 定义一个宏，用于标识智能家居的设备ID
#define DEVICE_ID "669dd4fec2e5fa1b1595ed03_DEVICE-XDW-001"
// 定义一个宏，用于标识用于MQTT连接的clientid
#define MQTT_CLIENT_ID "67eb96a85367f573f77e8956_DEVICE-TEST-001_0_1_2025040207"

// 定义一个宏，用于标识用于MQTT连接的username
#define MQTT_USERNAME "67eb96a85367f573f77e8956_DEVICE-TEST-001"

// 定义一个宏，用于标识用于MQTT连接的password
#define MQTT_PASSWORD "2d896989b1030ca52a6a8aa0be71149feb4fb345888a455926335b1aa6752369"



// 定义一个宏，用于标识设备属性上报所用的topic
#define PUBLISH_TOPIC "$oc/devices/"DEVICE_ID"/sys/properties/report"
// 定义一个宏，用于标识订阅下发命令所用的topic
#define SUBCRIB_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/#" 
// 定义一个宏，用于标识执行完成下发命令所返回响应的topic
#define RESPONSE_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/response"  

//定义用于mqtt连接的两个对象变量，对象类型来自mqtt三方库
Network network;    
MQTTClient client;

static unsigned char sendBuf[1000];
static unsigned char readBuf[1000];

// 定义光照度数据结构体
typedef struct {
    unsigned short light_value; // 存储光照度传感器的值
} LightSensorData;

// 假设这是读取光照度传感器数据的函数
uint32_t LightSensorReadData(LightSensorData *data) {
    // 调用光照度传感器的接口获取数据
    data->light_value = GetLightLevel(); // 使用之前定义的GetLightLevel函数
    return 0; // 假设总是成功，返回0
}

static void get_light_sensor_public_string(char *payload) {
    LightSensorData data = {0}; // 初始化LightSensorData结构体

    // 读取光照度传感器数据
    if (LightSensorReadData(&data) == 0) {
        // 将读取到的光照度传感器数据封装成JSON格式
        cJSON *root = cJSON_CreateObject(); // 创建JSON对象

        if (root != NULL) {
            // 创建数组，用于存放服务数据
            cJSON *serv_arr = cJSON_AddArrayToObject(root, "services");

            // 创建数组项，代表单个服务
            cJSON *arr_item = cJSON_CreateObject();

            // 添加服务ID
            cJSON_AddStringToObject(arr_item, "service_id", "service01");

            // 创建对象，用于存放属性
            cJSON *pro_obj = cJSON_CreateObject();
            cJSON_AddItemToObject(arr_item, "properties4", pro_obj);

            // 添加光照度传感器的数据到属性对象
            cJSON_AddNumberToObject(pro_obj, "light_value", (double)data.light_value);

            // 将服务数组项添加到服务数组中
            cJSON_AddItemToArray(serv_arr, arr_item);

            // 将JSON对象转换为字符串
            char *payload_str = cJSON_PrintUnformatted(root);
            if (payload_str != NULL) {
                strcpy(payload, payload_str); // 将JSON字符串复制到payload
                cJSON_free(payload_str); // 释放cJSON分配的内存
            }

            // 删除JSON对象，释放内存
            cJSON_Delete(root);
        }
    } else {
        // 处理读取传感器数据失败的情况
        printf("Failed to read data from light sensor.\n");
    }
}


static void MQTTDemoTask(void)
{
    //初始化光照度传感器
    GetLightLevel();

    printf(">> MQTTDemoTask ...\n");
    // 连接AP
    // 定义热点配置
    WifiDeviceConfig config = {0};
    // 设置热点配置中的SSID
    strcpy(config.ssid, PARAM_HOTSPOT_SSID);
    // 设置热点配置中的密码
    strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
    // 设置热点配置中的加密方式
    config.securityType = PARAM_HOTSPOT_TYPE;
    // 等待100ms
    osDelay(10);
    // 连接到热点
    int netId = ConnectToHotspot(&config);

    printf("wifi connect successful !\n");
    
    // 检查是否成功连接到热点
    if (netId < 0)
    {
        printf("Connect to AP failed!\r\n");
        return;
    }

    // 初始化并启动MQTT任务，连接MQTT服务器
    int rc;

    //初始化NetworkInit
    NetworkInit(&network);
    // 连接网络
    NetworkConnect(&network, HOST_ADDR, HOST_PORT);


    printf("MQTTClientInit  ...\n");

    MQTTClientInit(&client, &network, 2000, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));

    MQTTString clientId = MQTTString_initializer;
    clientId.cstring = MQTT_CLIENT_ID;
    MQTTString userName = MQTTString_initializer;
    userName.cstring = MQTT_USERNAME;
    MQTTString password = MQTTString_initializer;
    password.cstring = MQTT_PASSWORD;
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.clientID = clientId;
    data.username = userName;
	data.password = password;
    data.willFlag = 0;
    data.MQTTVersion = 4;
    data.keepAliveInterval = 60;
    data.cleansession = 1;
    printf("MQTTConnect  ...\n");
    
    rc = MQTTConnect(&client, &data);
    if (rc != 0) {
        printf("MQTTConnect: %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
    }

    printf("MQTTSubscribe  ...\n");
    while (1) {
        MQTTMessage message;
		char payload[500]={0};
        get_light_sensor_public_string(payload);
     
        message.qos = 0;
        message.retained = 0;
        message.payload = payload;
     
        message.payloadlen = strlen(payload);

        if ((rc = MQTTPublish(&client, PUBLISH_TOPIC, &message)) != 0) {
            printf("Return code from MQTT publish is %d\n", rc);
            NetworkDisconnect(&network);
            MQTTDisconnect(&client);
        }else{
            printf("mqtt publish success:%s\n",payload);
        }
        MQTTYield(&client, 5000);
    }
}  



static void OC_Demo(void)
{
    IoTWatchDogDisable();
    osThreadAttr_t attr;

    attr.name = "MQTTDemoTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = 24;

    if (osThreadNew((osThreadFunc_t)MQTTDemoTask, NULL, &attr) == NULL)
    {
        printf("Falied to create MQTTDemoTask!\n");
    }

}

APP_FEATURE_INIT(OC_Demo);
//SYS_RUN(OC_Demo);
